// Crop.cpp : implementation file
//

#include "stdafx.h"
#include "bookcap.h"
#include "bookcapDlg.h"
#include "Crop.h"

#define EVENT_FADEIN	1002

IMPLEMENT_DYNAMIC(CCrop, CWnd)

CCrop::CCrop(CbookcapDlg *parent)
{
	m_mousedown = 0;
	m_mouseX = -1;
	m_mouseY = -1;
	m_mouseXbase = -1;
	m_mouseYbase = -1;
	m_mouseXend = -1;
	m_mouseYend = -1;
	m_alpha = 0;

	m_SavedCursor = NULL;
	m_SelectionCursor = AfxGetApp()->LoadStandardCursor(IDC_CROSS);

	m_Parent = parent;
}

CCrop::~CCrop()
{

}


BEGIN_MESSAGE_MAP(CCrop, CWnd)
	ON_WM_CHAR()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_CREATE()
END_MESSAGE_MAP()


void CCrop::start()
{
	captureScreen();
	startCrop();
}

void CCrop::captureScreen()
{
	CDC *sDC = GetDesktopWindow()->GetWindowDC();
	if (sDC) {
		GetDesktopWindow()->GetWindowRect(&m_bigRect);
		m_captureDC.CreateCompatibleDC(sDC);
		m_captureBM.CreateCompatibleBitmap(sDC,m_bigRect.Width(),m_bigRect.Height());
		m_captureDC.SelectObject(&m_captureBM);
		m_captureDC.BitBlt(0,0,m_bigRect.Width(),m_bigRect.Height(),sDC,0,0,SRCCOPY);
		GetDesktopWindow()->ReleaseDC(sDC);

		m_shadeDC.CreateCompatibleDC(&m_captureDC);
		m_shadeBM.CreateCompatibleBitmap(&m_captureDC,m_bigRect.Width(),m_bigRect.Height());
		m_shadeDC.SelectObject(&m_shadeBM);
		m_shadeDC.BitBlt(0,0,m_bigRect.Width(),m_bigRect.Height(),&m_captureDC,0,0,SRCCOPY);

		m_backDC.CreateCompatibleDC(&m_captureDC);
		m_backBM.CreateCompatibleBitmap(&m_captureDC,m_bigRect.Width(),m_bigRect.Height());
		m_backDC.SelectObject(&m_backBM);

		m_smallRect = m_bigRect;
		m_alphaDC.CreateCompatibleDC(&m_captureDC);
		m_smallRect.right /= 8;
		m_smallRect.bottom /= 8;
		void *rawData = malloc(m_smallRect.right*m_smallRect.bottom*4);
		memset(rawData,0x10,m_smallRect.right*m_smallRect.bottom*4);
		m_alphaBM.CreateBitmap(m_smallRect.right,m_smallRect.bottom,1,32,rawData);
		free(rawData);
		m_alphaDC.SelectObject(m_alphaBM);
	}
}

void CCrop::startCrop()
{
	CreateEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,AfxRegisterWndClass(NULL),NULL,WS_POPUP,0,0,m_bigRect.Width(),m_bigRect.Height(),NULL,NULL);
	ShowWindow(SW_SHOW);
	SetCapture();
	m_SavedCursor = SetCursor(m_SelectionCursor);
}

void CCrop::cancel()
{
	ReleaseCapture();
	SetCursor(m_SavedCursor);
	m_Parent->cropCompleted(0);
}


void CCrop::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{	
	if (nChar == 27) {
		cancel();
		return;
	}

	CWnd::OnChar(nChar, nRepCnt, nFlags);
}


void CCrop::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_mousedown = 1;
	m_mouseX = point.x;
	m_mouseY = point.y;
	m_mouseXbase = m_mouseX;
	m_mouseYbase = m_mouseY;
	m_mouseXend = m_mouseX;
	m_mouseYend = m_mouseY;

	Invalidate();
}

void CCrop::OnLButtonUp(UINT nFlags, CPoint point)
{
	m_mousedown = 0;
	m_mouseX = point.x;
	m_mouseY = point.y;
	m_mouseXend = m_mouseX;
	m_mouseYend = m_mouseY;
	Invalidate();
	
	ShowWindow(SW_HIDE);

	if (m_mouseXbase > m_mouseXend) {
		int t = m_mouseXbase;
		m_mouseXbase = m_mouseXend;
		m_mouseXend = t;
	}

	if (m_mouseYbase > m_mouseYend) {
		int t = m_mouseYbase;
		m_mouseYbase = m_mouseYend;
		m_mouseYend = t;
	}

	if (m_mouseXend-m_mouseXbase < 10) {
		cancel();
		return;
	}

	if (m_mouseYend-m_mouseYbase < 10) {
		cancel();
		return;
	}
	
	ReleaseCapture();
	SetCursor(m_SavedCursor);
	m_Parent->cropCompleted(1);
}

void CCrop::OnMouseMove(UINT nFlags, CPoint point)
{
	m_mouseX = point.x;
	m_mouseY = point.y;	

	if (m_mousedown) {
		m_mouseXend = m_mouseX;
		m_mouseYend = m_mouseY;	
	}

	Invalidate();

//	CWnd::OnMouseMove(nFlags, point);
}

void CCrop::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	CRect rect;
	CPen blackPen(PS_SOLID,0,RGB(100,100,100));

	GetWindowRect(&rect);
	m_backDC.BitBlt(0,0,rect.Width(),rect.Height(),&m_shadeDC,rect.left,rect.top,SRCCOPY);

	if ((m_mouseXbase >= 0) && (m_mouseYbase >=0)) 
		m_backDC.BitBlt(m_mouseXbase,m_mouseYbase,m_mouseXend-m_mouseXbase,m_mouseYend-m_mouseYbase,&m_captureDC,rect.left+m_mouseXbase,rect.top+m_mouseYbase,SRCCOPY);
	else{
		m_backDC.SelectObject(&blackPen);
		m_backDC.MoveTo(m_mouseX,0);
		m_backDC.LineTo(m_mouseX,rect.bottom);
		m_backDC.MoveTo(0,m_mouseY);
		m_backDC.LineTo(rect.right,m_mouseY);
	}
	dc.BitBlt(0,0,rect.Width(),rect.Height(),&m_backDC,0,0,SRCCOPY);
}

void CCrop::OnTimer(UINT_PTR nIDEvent)
{
	if (nIDEvent == EVENT_FADEIN) {
		
		BLENDFUNCTION bf;
		bf.BlendOp = AC_SRC_OVER;
		bf.BlendFlags = 0;
		bf.SourceConstantAlpha = 0x10;             
		bf.AlphaFormat = 0;
		m_shadeDC.AlphaBlend(0,0,m_bigRect.Width(),m_bigRect.Height(),&m_alphaDC,0,0,m_smallRect.Width(),m_smallRect.Height(),bf);
		Invalidate();

		m_alpha++;
		if (m_alpha > 10)
			KillTimer(EVENT_FADEIN);
	}

	CWnd::OnTimer(nIDEvent);
}

int CCrop::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	SetTimer(EVENT_FADEIN,50,NULL);
	return 0;
}

int	CCrop::getSizeX()
{
	return m_mouseXend - m_mouseXbase;
}

int	CCrop::getSizeY()
{
	return m_mouseYend - m_mouseYbase;
}

COLORREF CCrop::getPixel(int x, int y)
{
	return m_captureDC.GetPixel(x + m_mouseXbase,y + m_mouseYbase);
}

